using B.S.XZYData.Api.Wrter.Application.Command.Process;
using B.S.XZYData.Domain.ZSHH;
using B.S.XZYData.Domain.RBAC;
using B.S.XZYData.Domain.ZSH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;
using System.Linq;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Process
{
    /// <summary>
    /// 导出工序处理器
    /// </summary>
    public class ExportProcessHandler : IRequestHandler<ExportProcessCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<Domain.ZSHH.Process> processRepo;
        private readonly IBaseRepository<RoleModel> roleRepo;
        private readonly IBaseRepository<Defective> defectiveRepo;
        private readonly ILogger<ExportProcessHandler> logger;

        public ExportProcessHandler(
            IBaseRepository<Domain.ZSHH.Process> processRepo,
            IBaseRepository<RoleModel> roleRepo,
            IBaseRepository<Defective> defectiveRepo,
            ILogger<ExportProcessHandler> logger)
        {
            this.processRepo = processRepo;
            this.roleRepo = roleRepo;
            this.defectiveRepo = defectiveRepo;
            this.logger = logger;
        }

        /// <summary>
        /// 导出工序
        /// </summary>
        /// <param name="request">命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回统一包装类</returns>
        public async Task<ApiResult<byte[]>> Handle(ExportProcessCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<byte[]>();

            try
            {
                // 构建查询条件
                var query = processRepo.GetAll().Where(x => !x.IsDeleted);

                if (!string.IsNullOrWhiteSpace(request.ProcessNumber))
                {
                    query = query.Where(x => x.ProcessNumber.Contains(request.ProcessNumber));
                }

                if (!string.IsNullOrWhiteSpace(request.ProcessName))
                {
                    query = query.Where(x => x.ProcessName.Contains(request.ProcessName));
                }

                var processList = query.ToList();

                if (!processList.Any())
                {
                    res.Msg = "没有找到符合条件的工序数据";
                    res.Code = ApiEnum.Fail;
                    return await System.Threading.Tasks.Task.FromResult(res);
                }

                // 导出为Excel
                var excelBytes = await ExportToExcel(processList);

                res.Data = excelBytes;
                res.Msg = $"导出成功，共 {processList.Count} 条记录";
                res.Code = ApiEnum.Success;

                logger.LogInformation($"导出工序成功，共 {processList.Count} 条记录，导出人：{request.Exporter}");

                return await System.Threading.Tasks.Task.FromResult(res);
            }
            catch (Exception ex)
            {
                logger.LogError($"导出工序异常：{ex.Message}");
                res.Msg = "导出工序异常：" + ex.Message;
                res.Code = ApiEnum.Error;
                return await System.Threading.Tasks.Task.FromResult(res);
            }
        }

        /// <summary>
        /// 导出为Excel
        /// </summary>
        /// <param name="processList">工序列表</param>
        /// <returns>Excel文件字节数组</returns>
        private async Task<byte[]> ExportToExcel(List<Domain.ZSHH.Process> processList)
        {
            // 创建工作簿
            IWorkbook workbook = new XSSFWorkbook();
            ISheet worksheet = workbook.CreateSheet("工序数据");

            // 创建表头样式
            ICellStyle headerStyle = workbook.CreateCellStyle();
            IFont headerFont = workbook.CreateFont();
            headerFont.IsBold = true;
            headerStyle.SetFont(headerFont);
            headerStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index;
            // headerStyle.FillPattern = FillPatternType.SolidForeground; // NPOI中不存在此属性
            headerStyle.BorderTop = BorderStyle.Thin;
            headerStyle.BorderBottom = BorderStyle.Thin;
            headerStyle.BorderLeft = BorderStyle.Thin;
            headerStyle.BorderRight = BorderStyle.Thin;

            // 创建数据样式
            ICellStyle dataStyle = workbook.CreateCellStyle();
            dataStyle.BorderTop = BorderStyle.Thin;
            dataStyle.BorderBottom = BorderStyle.Thin;
            dataStyle.BorderLeft = BorderStyle.Thin;
            dataStyle.BorderRight = BorderStyle.Thin;

            // 设置表头
            IRow headerRow = worksheet.CreateRow(0);
            string[] headers = { "工序编号", "工序名称", "报工权限", "报工数配比", "不良品项列表", "测试字段1", "测试字段2", "创建时间", "创建人", "修改时间", "修改人" };
            
            for (int i = 0; i < headers.Length; i++)
            {
                ICell cell = headerRow.CreateCell(i);
                cell.SetCellValue(headers[i]);
                cell.CellStyle = headerStyle;
            }

            // 填充数据
            for (int i = 0; i < processList.Count; i++)
            {
                var process = processList[i];
                IRow dataRow = worksheet.CreateRow(i + 1);

                dataRow.CreateCell(0).SetCellValue(process.ProcessNumber);
                dataRow.CreateCell(1).SetCellValue(process.ProcessName);
                dataRow.CreateCell(2).SetCellValue(await ConvertReportingPermissionsToNames(process.ReportingPermissions));
                dataRow.CreateCell(3).SetCellValue(process.ReportingRatio ?? 0);
                dataRow.CreateCell(4).SetCellValue(await ConvertDefectiveItemListToNames(process.DefectiveItemList));
                dataRow.CreateCell(5).SetCellValue(process.TestField1 ?? "");
                dataRow.CreateCell(6).SetCellValue(process.TestField2 ?? "");
                dataRow.CreateCell(7).SetCellValue(process.CreatorDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                dataRow.CreateCell(8).SetCellValue(process.Creator ?? "");
                dataRow.CreateCell(9).SetCellValue(process.UpdatorDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                dataRow.CreateCell(10).SetCellValue(process.Updator ?? "");

                // 应用数据样式
                for (int j = 0; j < 11; j++)
                {
                    dataRow.GetCell(j).CellStyle = dataStyle;
                }
            }

            // 自动调整列宽
            for (int i = 0; i < headers.Length; i++)
            {
                worksheet.AutoSizeColumn(i);
            }

            // 转换为字节数组
            using var ms = new MemoryStream();
            workbook.Write(ms);
            return ms.ToArray();
        }

        /// <summary>
        /// 将报工权限ID转换为角色名称
        /// </summary>
        /// <param name="permissionsText">报工权限ID文本</param>
        /// <returns>角色名称字符串</returns>
        private async Task<string> ConvertReportingPermissionsToNames(string permissionsText)
        {
            if (string.IsNullOrWhiteSpace(permissionsText))
                return "所有人";

            if (permissionsText == "0")
                return "所有人";

            var permissionIds = permissionsText.Split(',', StringSplitOptions.RemoveEmptyEntries)
                .Select(p => p.Trim())
                .Where(p => !string.IsNullOrWhiteSpace(p))
                .ToList();

            if (!permissionIds.Any())
                return "所有人";

            var roleNames = new List<string>();
            foreach (var permissionId in permissionIds)
            {
                if (long.TryParse(permissionId, out var roleId))
                {
                    var role = roleRepo.GetAll()
                        .Where(x => !x.IsDeleted && x.Id == roleId)
                        .ToList()
                        .FirstOrDefault();

                    if (role != null)
                    {
                        roleNames.Add(role.RoleName);
                    }
                    else
                    {
                        roleNames.Add($"未知角色({permissionId})");
                    }
                }
                else
                {
                    roleNames.Add($"无效ID({permissionId})");
                }
            }

            return roleNames.Any() ? string.Join(",", roleNames) : "所有人";
        }

        /// <summary>
        /// 将不良品项ID转换为不良品项名称
        /// </summary>
        /// <param name="defectiveText">不良品项文本</param>
        /// <returns>不良品项名称字符串</returns>
        private async Task<string> ConvertDefectiveItemListToNames(string defectiveText)
        {
            if (string.IsNullOrWhiteSpace(defectiveText))
                return string.Empty;

            // 解析简单的数字ID格式（如"1,2"、"1"）
            var defectiveIds = defectiveText.Split(',', StringSplitOptions.RemoveEmptyEntries)
                .Select(id => id.Trim())
                .Where(id => !string.IsNullOrWhiteSpace(id))
                .ToList();

            if (!defectiveIds.Any())
                return string.Empty;

            var resultItems = new List<string>();
            foreach (var id in defectiveIds)
            {
                if (long.TryParse(id, out var defectiveId))
                {
                    // 根据ID查找不良品项
                    var defective = defectiveRepo.GetAll()
                        .Where(x => !x.IsDeleted && x.Id == defectiveId)
                        .ToList()
                        .FirstOrDefault();

                    if (defective != null)
                    {
                        resultItems.Add($"{defective.DefectiveCode}|{defective.DefectiveName}");
                    }
                    else
                    {
                        // 如果找不到，保留原始ID
                        resultItems.Add($"未知({id})");
                    }
                }
                else
                {
                    // 如果不是数字ID，保留原始内容
                    resultItems.Add(id);
                }
            }

            return string.Join(",", resultItems);
        }
    }
} 